home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d14 / dde_lib.arc / SESSION.C < prev    next >
C/C++ Source or Header  |  1990-12-25  |  10KB  |  395 lines

  1. /* **********************************************************
  2.    session.c - Session DDE server for variable maintenance
  3.  
  4.    Placed in public domain by Horizon Technologies Inc. 1990
  5.  
  6.   ***revision history***
  7. 1 SESSION.C 29-Jan-90,10:23:54,`JMH' Base version
  8. 2 SESSION.C 19-Jun-90,10:51:18,`JMH' Version as of 6/25/90
  9. 3 SESSION.C 25-Jun-90,14:48:04,`JMH' Version as of 6/25/90
  10. 4 SESSION.C 15-Sep-90,16:19:56,`JMH' Version 1.3
  11.   ***revision history***
  12. ********************************************************** */
  13. #define MAIN
  14. #define NOCOMM
  15.  
  16. #include "windows.h"
  17. #include "stdio.h"
  18. #include "stdlib.h"
  19. #include "string.h"
  20. #include "dde.h"
  21. #include "ddelib.h"
  22. #include "session.h"
  23.  
  24. /* Undocumented windows functions */
  25. int FAR PASCAL lstrlen (LPSTR);
  26. LPSTR FAR PASCAL lstrcpy (LPSTR, LPSTR);
  27. LPSTR FAR PASCAL lstrcat (LPSTR, LPSTR);
  28. int FAR PASCAL lstrcmp (LPSTR, LPSTR);
  29.  
  30. /* Globals */
  31. static HANDLE ghInstance;
  32. static char *gszAppName = "Session";
  33. static FARPROC glpfnAbout;
  34. static DDECALLBACK glpfnSession;
  35. static HANDLE ghList = NULL;
  36.  
  37. /* Session variables */
  38. #define MAX_VARS 20
  39. static struct
  40. {
  41.    char szName[20];
  42.    char szValue[20];
  43. } gVars[MAX_VARS];
  44.  
  45. /* Functions */
  46. int PASCAL WinMain (HANDLE, HANDLE, LPSTR, int);
  47. long FAR PASCAL SessionProc (HWND, unsigned, WORD, LONG);
  48. WORD FAR PASCAL Session (HWND, unsigned, LPSTR, HANDLE);
  49. void SetString (LPSTR, LPSTR);
  50. void GetString (LPSTR, LPSTR);
  51. BOOL FAR PASCAL About (HWND, unsigned, WORD, LONG);
  52.  
  53.  
  54. int PASCAL WinMain (hInstance, hPrevInstance, lpCmdLine, nCmdShow)
  55. HANDLE hInstance;
  56. HANDLE hPrevInstance;
  57. LPSTR lpCmdLine;
  58. int nCmdShow;
  59. {
  60.    WNDCLASS wndclass;
  61.    MSG msg;
  62.    HWND hWnd;
  63.  
  64.    ghInstance = hInstance;
  65.  
  66.    if ( !hPrevInstance )
  67.       {
  68.       wndclass.style = CS_HREDRAW | CS_VREDRAW;
  69.       wndclass.lpfnWndProc = SessionProc;
  70.       wndclass.cbClsExtra = 0;
  71.       wndclass.cbWndExtra = 0;
  72.       wndclass.hInstance = hInstance;
  73.       wndclass.hIcon = LoadIcon ( hInstance, gszAppName );
  74.       wndclass.hCursor = LoadCursor ( NULL, IDC_ARROW );
  75.       wndclass.hbrBackground = (HBRUSH) GetStockObject ( WHITE_BRUSH );
  76.       wndclass.lpszMenuName = gszAppName;
  77.       wndclass.lpszClassName = gszAppName;
  78.  
  79.       if ( !RegisterClass ( &wndclass ) )
  80.      return FALSE;
  81.       }  /* if ! hPrevInstance */
  82.  
  83.    hWnd = CreateWindow ( gszAppName, gszAppName, WS_OVERLAPPEDWINDOW,
  84.              CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL,
  85.              hInstance, NULL );
  86.  
  87.    if ( !hWnd )
  88.       return ( NULL );
  89.  
  90.    ShowWindow ( hWnd, SW_SHOWMINIMIZED );
  91.    UpdateWindow ( hWnd );
  92.  
  93.    while ( GetMessage ( &msg, NULL, NULL, NULL ) )
  94.       {
  95.       TranslateMessage ( &msg );
  96.       DispatchMessage ( &msg );
  97.       }  /* while GetMessage */
  98.  
  99.    return ( msg.wParam );
  100. }  /* function WinMain */
  101.  
  102.  
  103. long FAR PASCAL SessionProc (hWnd, iMessage, wParam, lParam)
  104. HWND hWnd;
  105. unsigned iMessage;
  106. WORD wParam;
  107. LONG lParam;
  108. {
  109.    static HANDLE hTopic;
  110.  
  111.    switch ( iMessage )
  112.       {
  113.       case WM_CREATE:
  114.      /* Provide callback addresses for DDE callback function */
  115.      glpfnSession = (DDECALLBACK) MakeProcInstance ( (FARPROC) Session,
  116.                              ghInstance );
  117.  
  118.      /* Register the DDE Topic */
  119.      hTopic = DDERegisterTopic ( hWnd, gszAppName, "Variables",
  120.                      glpfnSession );
  121.      break;
  122.  
  123.       case WM_COMMAND:
  124.      switch ( wParam )
  125.         {
  126.         case IDM_EXIT:
  127.            SendMessage ( hWnd, WM_CLOSE, 0, 0L );
  128.            break;
  129.  
  130.         case IDM_ABOUT:
  131.            glpfnAbout = MakeProcInstance ( About, ghInstance );
  132.            DialogBox ( ghInstance, "About", hWnd, glpfnAbout );
  133.            FreeProcInstance ( glpfnAbout );
  134.            break;
  135.         }  /* switch wParam */
  136.      break;
  137.  
  138.       case WM_DESTROY:
  139.      /* Unregister the DDE Topic */
  140.      DDEUnregisterTopic ( hTopic );
  141.      PostQuitMessage ( 0 );
  142.      break;
  143.  
  144.       default:
  145.      return DefWindowProc ( hWnd, iMessage, wParam, lParam );
  146.       }  /* switch iMessage */
  147.  
  148.    return 0L;
  149. }  /* function SessionProc */
  150.  
  151.  
  152. /* Callback routine to notify of client activity */
  153. WORD FAR PASCAL Session (hSession, iMessage, lpszItem, hDataIn)
  154. HWND hSession;
  155. unsigned iMessage;
  156. LPSTR lpszItem;
  157. HANDLE hDataIn;
  158. {
  159.    HANDLE hDataOut;
  160.    DDEACK wAck;
  161.    LPDDEDATA lpData;
  162.    LPDDEPOKE lpPoke;
  163.    LPDDEADVISE lpAdvise;
  164.    LPSTR lpCommand;
  165.    char szData[100];
  166.  
  167.    /* Set up return value */
  168.    wAck.bAppReturnCode = 0;
  169.    wAck.reserved = 0;
  170.    wAck.fBusy = FALSE;
  171.    wAck.fAck = TRUE;
  172.  
  173.    /* Switch on the message */
  174.    switch ( iMessage )
  175.       {
  176.       case DDE_INITIATE:
  177.      break;
  178.  
  179.       case DDE_TERMINATE:
  180.      ghList = DDEUnregisterAdvise ( ghList, hSession, NULL );
  181.      break;
  182.  
  183.       case DDE_POKE:
  184.      /* Get pointer to poke structure */
  185.      lpPoke = (LPDDEPOKE) GlobalLock ( hDataIn );
  186.  
  187.      /* Accept only text */
  188.      if ( lpPoke && lpPoke->cfFormat == CF_TEXT )
  189.         SetString ( lpszItem, lpPoke->Value );
  190.  
  191.      /* Reject all else */
  192.      else
  193.         wAck.fAck = FALSE;
  194.  
  195.      /* Clean up */
  196.      if ( lpPoke )
  197.         GlobalUnlock ( hDataIn );
  198.      break;
  199.  
  200.       case DDE_REQUEST:
  201.      /* Get pointer to advise structure */
  202.      lpAdvise = (LPDDEADVISE) GlobalLock ( hDataIn );
  203.  
  204.      /* Accept only text */
  205.      if ( lpAdvise && lpAdvise->cfFormat == CF_TEXT )
  206.         {
  207.         /* Get the current value */
  208.         GetString ( lpszItem, szData );
  209.  
  210.         /* Create a DDEDATA structure to send the client */
  211.         hDataOut = GlobalAlloc ( GHND | GMEM_DDESHARE, (DWORD) sizeof (
  212.                      DDEDATA ) + strlen ( szData ) );
  213.  
  214.         /* Set its members */
  215.         lpData = (LPDDEDATA) GlobalLock ( hDataOut );
  216.         lpData->fRelease = TRUE;
  217.         lpData->fAckReq = FALSE;
  218.         lpData->cfFormat = CF_TEXT;
  219.         lstrcpy ( lpData->Value, szData );
  220.         GlobalUnlock ( hDataOut );
  221.  
  222.         /* Send the data */
  223.         DDESendData ( hSession, DDE_REQUEST, lpszItem, hDataOut );
  224.         }  /* if lpAdvise */
  225.  
  226.      /* Reject all else */
  227.      else
  228.         wAck.fAck = FALSE;
  229.  
  230.      /* Clean up */
  231.      if ( lpAdvise )
  232.         GlobalUnlock ( hDataIn );
  233.      break;
  234.  
  235.       case DDE_EXECUTE:
  236.      /* Get pointer to command string */
  237.      lpCommand = GlobalLock ( hDataIn );
  238.  
  239.      /* Process command here */
  240.  
  241.      /* Ack bad - we do not accept commands yet */
  242.      wAck.fAck = FALSE;
  243.  
  244.      /* Clean up */
  245.      if ( lpCommand )
  246.         GlobalUnlock ( hDataIn );
  247.      break;
  248.  
  249.       case DDE_ADVISE:
  250.      /* Get pointer to advise structure */
  251.      lpAdvise = (LPDDEADVISE) GlobalLock ( hDataIn );
  252.  
  253.      /* Accept only text */
  254.      if ( lpAdvise && lpAdvise->cfFormat == CF_TEXT )
  255.         ghList = DDERegisterAdvise ( ghList, hSession, lpszItem,
  256.                      lpAdvise->fAckReq, lpAdvise->fDeferUpd,
  257.                      CF_TEXT );
  258.  
  259.      /* Reject all else */
  260.      else
  261.         wAck.fAck = FALSE;
  262.  
  263.      /* Clean up */
  264.      if ( lpAdvise )
  265.         GlobalUnlock ( hDataIn );
  266.      break;
  267.  
  268.       case DDE_UNADVISE:
  269.      ghList = DDEUnregisterAdvise ( ghList, hSession, lpszItem );
  270.      break;
  271.       }  /* switch iMessage */
  272.  
  273.    return *(WORD *) &wAck;
  274. }  /* function Session */
  275.  
  276.  
  277. /* Set the value of some string */
  278. void SetString (lpszString, lpszValue)
  279. LPSTR lpszString;
  280. LPSTR lpszValue;
  281. {
  282.    HANDLE hData = NULL;
  283.    LPDDEDATA lpData;
  284.    int iVar;
  285.    int iEmpty = MAX_VARS;
  286.    int nItem = 0;
  287.    HANDLE hSession;
  288.    char szItem[20];
  289.    int fAckReq;
  290.    int fDeferUpd;
  291.    int cfFormat;
  292.  
  293.    /* Replace it if it exists */
  294.    for ( iVar = 0; iVar < MAX_VARS; iVar++ )
  295.       {
  296.       /* Found it: update and quit */
  297.       if ( lstrcmp ( gVars [iVar].szName, lpszString ) == 0 )
  298.      {
  299.      lstrcpy ( gVars [iVar].szValue, lpszValue );
  300.      break;
  301.      }  /* if lstrcmp */
  302.  
  303.       /* Found an empty slot, save its position */
  304.       if ( iEmpty == MAX_VARS && strlen ( gVars [iVar].szName ) == 0 )
  305.      iEmpty = iVar;
  306.       }  /* for iVar */
  307.  
  308.    /* Add it if it does not exist and there is room */
  309.    if ( iVar == MAX_VARS && iEmpty != MAX_VARS )
  310.       {
  311.       iVar = iEmpty;
  312.       lstrcpy ( gVars [iVar].szName, lpszString );
  313.       lstrcpy ( gVars [iVar].szValue, lpszValue );
  314.       }  /* if iVar */
  315.  
  316.    /* Update the world */
  317.    if ( iVar != MAX_VARS )
  318.       {
  319.       /* Loop through the advise list */
  320.       while ( DDEGetAdvise ( ghList, nItem++, &hSession, szItem,
  321.                  sizeof ( szItem ), &fAckReq, &fDeferUpd,
  322.                  &cfFormat ) != -1 )
  323.      {
  324.      /* If advised on this variable */
  325.      if ( lstrcmp ( lpszString, szItem ) == 0 )
  326.         {
  327.         /* If the client asked for a "hot" link */
  328.         if ( ! fDeferUpd )
  329.            {
  330.            /* Create a DDEDATA structure to send the client */
  331.            hData = GlobalAlloc ( GHND | GMEM_DDESHARE, (DWORD) sizeof (
  332.                      DDEDATA ) + lstrlen ( lpszValue ) );
  333.  
  334.            /* Set its members */
  335.            lpData = (LPDDEDATA) GlobalLock ( hData );
  336.            lpData->fRelease = TRUE;
  337.            lpData->fAckReq = fAckReq;
  338.            lpData->cfFormat = cfFormat;
  339.            lstrcpy ( lpData->Value, lpszValue );
  340.            GlobalUnlock ( hData );
  341.            }
  342.  
  343.         /* Send the data */
  344.         DDESendData ( hSession, DDE_ADVISE, lpszString, hData );
  345.         }  /* if lstrcmp */
  346.      }  /* for iAdvise */
  347.       }  /* if iVar */
  348. }  /* function SetString */
  349.  
  350.  
  351. /* Get the value of some string */
  352. void GetString (lpszString, lpszValue)
  353. LPSTR lpszString;
  354. LPSTR lpszValue;
  355. {
  356.    int iVar;
  357.  
  358.    /* Default to blank */
  359.    lstrcpy ( lpszValue, "" );
  360.  
  361.    /* Find the value of some string */
  362.    for ( iVar = 0; iVar < MAX_VARS; iVar++ )
  363.       {
  364.       /* Found it */
  365.       if ( lstrcmp ( gVars [iVar].szName, lpszString ) == 0 )
  366.      {
  367.      lstrcpy ( lpszValue, gVars [iVar].szValue );
  368.      break;
  369.      }  /* if lstrcmp */
  370.       }  /* for iVar */
  371. }  /* function GetString */
  372.  
  373.  
  374. /* About box */
  375. BOOL FAR PASCAL About (hDlg, iMessage, wParam, lParam)
  376. HWND hDlg;
  377. unsigned iMessage;
  378. WORD wParam;
  379. LONG lParam;
  380. {
  381.    switch ( iMessage )
  382.       {
  383.       case WM_INITDIALOG:
  384.      break;
  385.  
  386.       case WM_COMMAND:
  387.      EndDialog ( hDlg, FALSE );
  388.      break;
  389.  
  390.       default:
  391.      return FALSE;
  392.       }  /* switch iMessage */
  393.    return TRUE;
  394. }  /* function About */
  395.